/*
 * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifdef __cplusplus
extern "C" {
#endif // __cplusplus

#include "sle_lite_tool_ssap_server.h"

void OnTRequestReadCb(SleErrorCode errCode, uint8_t serverId,
         uint16_t connectId, const SsapsReqReadCbParam *readCbPara)
{
    printf("[SleSsapServerTestTool] OnTRequestReadCb (%d:%d)(%s:%d)\r\n", connectId, serverId
        , SsapPropertyTypeStr(readCbPara->type), readCbPara->handle);
}

void OnTRequestWriteCb(SleErrorCode errCode, uint8_t serverId,
         uint16_t connectId, const SsapsReqWriteCbPara *writeCbPara)
{
//    printf("[SleSsapServerTestTool] OnTRequestWriteCb (%d:%d)(%s:%d) %s\r\n", connectId, serverId
//        , SsapPropertyTypeStr(writeCbPara->type), writeCbPara->handle, writeCbPara->value);
}

void OnTChangeMtuCb(SleErrorCode errCode, uint8_t serverId, uint16_t connectId, const SsapMtuInfo *mtuInfo)
{
    printf("[SleSsapServerTestTool] OnTChangeMtuCb(%d) serverId(%d) connectId(%d) mtuSize(%u)\r\n", errCode
        , serverId, connectId, mtuInfo->mtuSize);
}

static uint8_t g_serverId;
void TAddSsapServer(void)
{
    SleUuid appUuid;
    memcpy(appUuid.uuid, "sleToolSsaps", strlen("sleToolSsaps"));
    appUuid.len = strlen("sleToolSsaps");
    SleErrorCode ret = AddSsapServer(&appUuid, &g_serverId);
    if(ret != SLE_NO_ERROR) {
        printf("[SleSsapServerTestTool] AddSsapServer failed(%hhu)\r\n", ret);
        return;
    }
    SLE_TEST_TOOL_LOG("[SleSsapServerTestTool] AddSsapServer success serverId(%d)", g_serverId);
}

void TRemoveSsapServer(void)
{
    uint8_t serverId = (uint8_t)SleGetInputNumber("Please input serverId:");
    SleErrorCode ret = RemoveSsapServer(serverId);
    if(ret != SLE_NO_ERROR) {
        printf("[SleSsapServerTestTool] RemoveSsapServer failed(%hhu)\r\n", ret);
        return;
    }
    SLE_TEST_TOOL_LOG("[SleSsapServerTestTool] RemoveSsapServer success serverId(%d)", serverId);
}

void TAddService(void)
{
    uint8_t serverId = (uint8_t)SleGetInputNumber("Please input serverId:");
    uint16_t serviceHandle;
    SleUuid serviceUuid;
    memcpy(serviceUuid.uuid, "sleToolService", strlen("sleToolService"));
    serviceUuid.len = strlen("sleToolService");
    bool isPrimary = true;
    SleErrorCode ret = AddService(serverId, &serviceUuid, isPrimary, &serviceHandle);
    if(ret != SLE_NO_ERROR) {
        printf("[SleSsapServerTestTool] AddService failed(%hhu)\r\n", ret);
        return;
    }
    SLE_TEST_TOOL_LOG("[SleSsapServerTestTool] AddService success serverId(%d) serviceHandle(%d)", serverId, serviceHandle);
}

void TAddProperty(void)
{
    SsapsPropertyParam param = {
        .permissions = SSAP_PERMISSION_CAN_READ | SSAP_PERMISSION_CAN_WRITE,
        .opIndication = SSAP_OPERATEIND_BIT_WRITE | SSAP_OPERATEIND_BIT_NOTIFY,
        .value = (uint8_t*)"SleTestProperty",
        .valueLen = strlen("SleTestProperty"),
    };
    uint16_t propertyHandle;
    memcpy(param.uuid.uuid, "sleToolProp", strlen("sleToolProp"));
    param.uuid.len = strlen("sleToolProp");
    uint8_t serverId = (uint8_t)SleGetInputNumber("Please input serverId:");
    uint16_t serviceHandle = (uint8_t)SleGetInputNumber("Please input serviceHandle:");
    // param.permissions = (uint8_t)SleGetInputNumber("Please input permissions:");
    // param.opIndication = (uint8_t)SleGetInputNumber("Please input opIndication:");
    SleErrorCode ret = AddProperty(serverId, serviceHandle, &param, &propertyHandle);
    if(ret != SLE_NO_ERROR) {
        printf("[SleSsapServerTestTool] AddProperty failed(%hhu)\r\n", ret);
        return;
    }
    SLE_TEST_TOOL_LOG("[SleSsapServerTestTool] AddProperty success serverId(%d) serviceHandle(%d) propertyHandle(%d)", serverId, serviceHandle, propertyHandle);
}

void TAddDescriptor(void)
{
    SsapsDescriptorParam descParam = {
        .permissions = SSAP_PERMISSION_CAN_READ | SSAP_PERMISSION_CAN_WRITE,
        .operateInd = SSAP_OPERATEIND_BIT_WRITE_NO_RSP,
        .type = SSAP_DESCRIPTOR_TYPE_CLIENT_CONFIGURATION_TYPE,
        .value = (uint8_t*)"SleTestDespriptor",
        .valueLen = strlen("SleTestDespriptor"),
    };
    memcpy(descParam.uuid.uuid, "sleToolDesp", strlen("sleToolDesp"));
    descParam.uuid.len = strlen("sleToolDesp");
    uint16_t descHandle;
    uint8_t serverId = (uint8_t)SleGetInputNumber("Please input serverId:");
    uint16_t serviceHandle = (uint8_t)SleGetInputNumber("Please input serviceHandle:");
    uint16_t propertyHandle = SleGetInputNumber("Please input propertyHandle:");
    // descParam.permissions = (uint8_t)SleGetInputNumber("Please input permissions:");
    // descParam.operateInd = (uint8_t)SleGetInputNumber("Please input opIndication:");
    SleErrorCode ret = AddDescriptor(serverId, serviceHandle, propertyHandle, &descParam, &descHandle);
    if(ret != SLE_NO_ERROR) {
        printf("[SleSsapServerTestTool] AddDescriptor failed(%hhu)\r\n", ret);
        return;
    }
    SLE_TEST_TOOL_LOG("[SleSsapServerTestTool] AddDescriptor success serverId(%d) serviceHandle(%d) propertyHandle(%d) descptorHandle(%d)"
        , serverId, serviceHandle, propertyHandle, descHandle);
}

void TRemoveAllServices(void)
{
    uint8_t serverId = (uint8_t)SleGetInputNumber("Please input serverId:");
    SleErrorCode ret = RemoveAllServices(serverId);
    if(ret != SLE_NO_ERROR) {
        printf("[SleSsapServerTestTool] RemoveAllServices failed(%hhu)\r\n", ret);
        return;
    }
    SLE_TEST_TOOL_LOG("[SleSsapServerTestTool] RemoveAllServices success serverId(%d)", serverId);
}

void TStartService(void)
{
    uint8_t serverId = (uint8_t)SleGetInputNumber("Please input serverId:");
    uint16_t serviceHandle = (uint8_t)SleGetInputNumber("Please input serviceHandle:");
    SleErrorCode ret = StartService(serverId, serviceHandle);
    if(ret != SLE_NO_ERROR) {
        printf("[SleSsapServerTestTool] StartService failed(%hhu)\r\n", ret);
        return;
    }
    SLE_TEST_TOOL_LOG("[SleSsapServerTestTool] StartService success serverId(%d) serviceHandle(%d)", serverId, serviceHandle);
}

void TSendResponse(void)
{
    uint16_t connectId = (uint16_t)SleGetInputNumber("Please input connectId:");
    uint8_t serverId = (uint8_t)SleGetInputNumber("Please input serverId:");
    SsapsSendRspParam param;
    param.requestId = (uint16_t)SleGetInputNumber("Please input requestId:");
    param.status = 0;
    char value[257];
    SleGetInputString("Please input value:", value, 257);
    param.valueLen = strlen(value);
    param.value = (uint8_t*)malloc(param.valueLen * sizeof(uint8_t));
    memcpy(param.value, value, strlen(value));

    SleErrorCode ret = SendResponse(serverId, connectId, &param);
    free(param.value);
    if(ret != SLE_NO_ERROR) {
        printf("[SleSsapServerTestTool] SendResponse failed(%hhu)\r\n", ret);
        return;
    }
}

void TNotifyIndicate(void)
{
    uint16_t connectId = (uint16_t)SleGetInputNumber("Please input connectId:");
    uint8_t serverId = (uint8_t)SleGetInputNumber("Please input serverId:");
    SsapsNotifyParam param;
    param.handle = (uint16_t)SleGetInputNumber("Please input handle:");
    param.type = (SsapPropertyType)SleGetInputNumber("Please input type:");
    char value[257];
    SleGetInputString("Please input value:", value, 257);
    param.valueLen = strlen(value);
    param.value = (uint8_t*)malloc(param.valueLen * sizeof(uint8_t));
    memcpy(param.value, value, strlen(value));

    SleErrorCode ret = NotifyIndicate(serverId, connectId, &param);
    free(param.value);
    if(ret != SLE_NO_ERROR) {
        printf("[SleSsapServerTestTool] NotifyIndicate failed(%hhu)\r\n", ret);
        return;
    }
}

void TNotifyIndicateByUuid(void)
{
    uint16_t connectId = (uint16_t)SleGetInputNumber("Please input connectId:");
    uint8_t serverId = (uint8_t)SleGetInputNumber("Please input serverId:");
    SsapsNotyfyByUuidParam param;
    char temp[UUID_LEN + 1];
    SleGetInputString("Please input uuid(<=16) ", temp, UUID_LEN + 1);
    memcpy(param.uuid.uuid, temp, strlen(temp));
    param.uuid.len = strlen(temp);
    param.startHandle = (uint16_t)SleGetInputNumber("Please input start handle:");
    param.endHandle = (uint16_t)SleGetInputNumber("Please input end handle:");
    param.type = (SsapPropertyType)SleGetInputNumber("Please input type:");
    char value[257];
    SleGetInputString("Please input value:", value, 257);
    param.valueLen = strlen(value);
    param.value = (uint8_t*)malloc(param.valueLen * sizeof(uint8_t));
    memcpy(param.value, value, strlen(value));
    SleErrorCode ret = NotifyIndicateByUuid(serverId, connectId, &param);
    free(param.value);
    if(ret != SLE_NO_ERROR) {
        printf("[SleSsapServerTestTool] NotifyIndicate failed(%hhu)\r\n", ret);
        return;
    }
}

void TSetServerMtuInfo(void)
{
    uint8_t serverId = (uint8_t)SleGetInputNumber("Please input serverId:");
    SsapMtuInfo mtuInfo;
    mtuInfo.mtuSize = (uint32_t)SleGetInputNumber("Please input mtuSize:");
    SleErrorCode ret = SetServerMtuInfo(serverId, &mtuInfo);
    if(ret != SLE_NO_ERROR) {
        printf("[SleSsapServerTestTool] SetServerMtuInfo failed(%hhu)\r\n", ret);
        return;
    }
}

void SleSsapServerToolHalper(void)
{
    printf("***SleSsapServerTool Command List****\r\n");
    for (uint16_t i = 0; i < g_ssapServerCmdNum; i++) {
        printf("*     %02d - %-20s     *\r\n", i, g_ssapServerCmdList[i].desc);
    }
    printf("*************************************\r\n");
}

void SleSsapServerToolCmdHandler(int argc, char **argv)
{
    printf("SleSsapServerToolCmdHandler in\r\n");
    //试配uart接口的调用方式
    SleResetEnv();
    //从函数名字之后开始处理参数列表
    SleSetBufEnv(argc, argv, 1);
    int index = SleGetInputNumber("Please input cmd index:\r\n");
    if(index < g_ssapServerCmdNum) {
        printf("cmd: %d\r\n", index);
        printf("Execute: %s\r\n", g_ssapServerCmdList[index].desc);
        g_ssapServerCmdList[index].func();
    }
    if(index != 0) g_ssapServerCmdList[0].func();
}

#ifdef __cplusplus
}
#endif // __cplusplus
